﻿using Heroius.Extension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CNEMC_WPF
{
    /// <summary>
    /// 全局唯一的显示内容控制选项
    /// </summary>
    public class ControlContext : INotifyPropertyChanged
    {
        public ControlContext(string basepath)
        {
            BasePath = basepath;
            Stations = new ObservableCollection<StationInfo>();
            Log = new ObservableCollection<string>();
            Diagram = new StationDiagram();
            Contour = new StationContour();
            Data = new ObservableCollection<DataRecord>();
            LoadedDataFiles = new ObservableCollection<string>();
        }

        public double R_E { get; set; } = 135.05;
        public double R_W { get; set; } = 73.66;
        public double R_N { get; set; } = 53.55;
        public double R_S { get; set; } = 3.86;

        //存放程序路径
        string BasePath;
        //站点列表文件名
        public string StationFileName { get; set; } = "stations.csv";
        /// <summary>
        /// 图片图层文件名
        /// </summary>
        public string KmlFilePath { get { return $"{BasePath}\\contour.kml"; } }
        /// <summary>
        /// 图片图层文件名
        /// </summary>
        public string ContourImagePath { get { return $"{BasePath}\\contour.png"; } }
        /// <summary>
        /// 生成等值线时单个边的网格数量
        /// </summary>
        public int ContourMeshCount { get; set; } = 300;

        /// <summary>
        /// 读取站点信息文件
        /// </summary>
        public void LoadStationFile()
        {
            Stations.Clear();
            using (StreamReader sr = new StreamReader($"{BasePath}\\{StationFileName}", Encoding.UTF8))
            {
                sr.ReadLine(); //headline

                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        var parts = line.Split(',');
                        string des = "缺少标识";
                        if (parts.Length < 5)
                        {
                            if (parts.Length >= 2)
                                des = $"{parts[0]} {parts[1]}";
                            Log.Add($"跳过记录：{des}");
                        }
                        else
                        {
                            try
                            {
                                var station = new StationInfo()
                                {
                                    Code = parts[0],
                                    Name = parts[1],
                                    City = parts[2],
                                    Longitude = Convert.ToDouble(parts[3]),
                                    Latitude = Convert.ToDouble(parts[4])
                                };
                                Stations.Add(station);
                            }
                            catch
                            {
                                des = $"{parts[0]} {parts[1]}";
                                Log.Add($"跳过记录：{des}");
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 缓存站点信息
        /// </summary>
        public ObservableCollection<StationInfo> Stations { get; set; }

        /// <summary>
        /// 设置或获取激活的站点，可在面板中查看此站点的数据
        /// </summary>
        public StationInfo SelectedStation
        {
            get { return _SelectedStation; }
            set { _SelectedStation = value; RaisePropertyChangedEvent("SelectedStation"); }
        }
        StationInfo _SelectedStation;

        /// <summary>
        /// 单个站点制图配置
        /// </summary>
        public StationDiagram Diagram { get; set; }
        /// <summary>
        ///  地图等值线配置
        /// </summary>
        public StationContour Contour { get; set; }

        /// <summary>
        /// 缓存数据
        /// </summary>

        public ObservableCollection<DataRecord> Data { get; set; }
        /// <summary>
        /// 记录已经加载的数据文件名
        /// </summary>
        public ObservableCollection<string> LoadedDataFiles { get; set; }

        /// <summary>
        /// 读取数据文件
        /// </summary>
        /// <param name="filepath">数据文件路径</param>
        public void LoadDataFile(string filepath)
        {
            using (StreamReader sr = new StreamReader(filepath, Encoding.UTF8))
            {
                //此处使用封装的库来操作CSV格式，可与 LoadStationFile 对比
                var heads = Heroius.Files.CSV.CsvHelper.ReadLine(sr.ReadLine());
                while (!sr.EndOfStream)
                {
                    var parts = Heroius.Files.CSV.CsvHelper.ReadLine(sr.ReadLine());
                    //注意以下转换使用了封装库提供的方法，与 Convert 类对比学习
                    DateTime dt = new DateTime(
                        parts[0].Substring(0, 4).As<int>(),
                        parts[0].Substring(4, 2).As<int>(),
                        parts[0].Substring(6).As<int>(),
                        parts[1].As<int>(), 0, 0
                    );
                    //枚举类型的转换方法，可与 Enum.Parse 对比；转换前，对文本进行处理，以使其与枚举命名一致
                    Pollutant pl = parts[2].Replace(".", "").ToUpper().As<Pollutant>(); 

                    for (int i = 3; i < parts.Count; i++) //从第3列开始为数值
                    {
                        if (!string.IsNullOrWhiteSpace(parts[i])) //判断是否有数值
                        {
                            var code = heads[i]; //从头部获取站点编号
                            Data.Add(new DataRecord() {
                                StationCode = code,
                                Time = dt,
                                Item = pl,
                                Value = parts[i].As<double>()
                            });
                        }
                    }
                }
            }
            //添加文件名
            LoadedDataFiles.Add(new FileInfo(filepath).Name);
        }

        /// <summary>
        /// 日志
        /// </summary>
        public ObservableCollection<string> Log { get; set; }


        #region Property Notification Interface

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChangedEvent(string PropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }

        #endregion

    }
}
